home *** CD-ROM | disk | FTP | other *** search
/ Ultra Pack / UltraComputing Partner Applications.iso / SunLabs / tclTK / src / tk4.0 / tkCanvWind.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  24KB  |  833 lines

  1. /* 
  2.  * tkCanvWind.c --
  3.  *
  4.  *    This file implements window items for canvas widgets.
  5.  *
  6.  * Copyright (c) 1992-1994 The Regents of the University of California.
  7.  * Copyright (c) 1994-1995 Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  */
  12.  
  13. static char sccsid[] = "@(#) tkCanvWind.c 1.18 95/03/17 16:01:46";
  14.  
  15. #include <stdio.h>
  16. #include "tkInt.h"
  17. #include "tkPort.h"
  18. #include "tkCanvas.h"
  19.  
  20. /*
  21.  * The structure below defines the record for each window item.
  22.  */
  23.  
  24. typedef struct WindowItem  {
  25.     Tk_Item header;        /* Generic stuff that's the same for all
  26.                  * types.  MUST BE FIRST IN STRUCTURE. */
  27.     double x, y;        /* Coordinates of positioning point for
  28.                  * window. */
  29.     Tk_Window tkwin;        /* Window associated with item.  NULL means
  30.                  * window has been destroyed. */
  31.     int width;            /* Width to use for window (<= 0 means use
  32.                  * window's requested width). */
  33.     int height;            /* Width to use for window (<= 0 means use
  34.                  * window's requested width). */
  35.     Tk_Anchor anchor;        /* Where to anchor window relative to
  36.                  * (x,y). */
  37.     Tk_Canvas canvas;        /* Canvas containing this item. */
  38. } WindowItem;
  39.  
  40. /*
  41.  * Information used for parsing configuration specs:
  42.  */
  43.  
  44. static Tk_ConfigSpec configSpecs[] = {
  45.     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
  46.     "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
  47.     {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
  48.     "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
  49.     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
  50.     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tk_CanvasTagsOption},
  51.     {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
  52.     "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},
  53.     {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
  54.     (char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
  55.     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
  56.     (char *) NULL, 0, 0}
  57. };
  58.  
  59. /*
  60.  * Prototypes for procedures defined in this file:
  61.  */
  62.  
  63. static void        ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas canvas,
  64.                 WindowItem *winItemPtr));
  65. static int        ConfigureWinItem _ANSI_ARGS_((Tcl_Interp *interp,
  66.                 Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
  67.                 char **argv, int flags));
  68. static int        CreateWinItem _ANSI_ARGS_((Tcl_Interp *interp,
  69.                 Tk_Canvas canvas, struct Tk_Item *itemPtr,
  70.                 int argc, char **argv));
  71. static void        DeleteWinItem _ANSI_ARGS_((Tk_Canvas canvas,
  72.                 Tk_Item *itemPtr, Display *display));
  73. static void        DisplayWinItem _ANSI_ARGS_((Tk_Canvas canvas,
  74.                 Tk_Item *itemPtr, Display *display, Drawable dst,
  75.                 int x, int y, int width, int height));
  76. static void        ScaleWinItem _ANSI_ARGS_((Tk_Canvas canvas,
  77.                 Tk_Item *itemPtr, double originX, double originY,
  78.                 double scaleX, double scaleY));
  79. static void        TranslateWinItem _ANSI_ARGS_((Tk_Canvas canvas,
  80.                 Tk_Item *itemPtr, double deltaX, double deltaY));
  81. static int        WinItemCoords _ANSI_ARGS_((Tcl_Interp *interp,
  82.                 Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
  83.                 char **argv));
  84. static void        WinItemLostSlaveProc _ANSI_ARGS_((
  85.                 ClientData clientData, Tk_Window tkwin));
  86. static void        WinItemRequestProc _ANSI_ARGS_((ClientData clientData,
  87.                 Tk_Window tkwin));
  88. static void        WinItemStructureProc _ANSI_ARGS_((
  89.                 ClientData clientData, XEvent *eventPtr));
  90. static int        WinItemToArea _ANSI_ARGS_((Tk_Canvas canvas,
  91.                 Tk_Item *itemPtr, double *rectPtr));
  92. static double        WinItemToPoint _ANSI_ARGS_((Tk_Canvas canvas,
  93.                 Tk_Item *itemPtr, double *pointPtr));
  94.  
  95. /*
  96.  * The structure below defines the window item type by means of procedures
  97.  * that can be invoked by generic item code.
  98.  */
  99.  
  100. Tk_ItemType tkWindowType = {
  101.     "window",                /* name */
  102.     sizeof(WindowItem),            /* itemSize */
  103.     CreateWinItem,            /* createProc */
  104.     configSpecs,            /* configSpecs */
  105.     ConfigureWinItem,            /* configureProc */
  106.     WinItemCoords,            /* coordProc */
  107.     DeleteWinItem,            /* deleteProc */
  108.     DisplayWinItem,            /* displayProc */
  109.     1,                    /* alwaysRedraw */
  110.     WinItemToPoint,            /* pointProc */
  111.     WinItemToArea,            /* areaProc */
  112.     (Tk_ItemPostscriptProc *) NULL,    /* postscriptProc */
  113.     ScaleWinItem,            /* scaleProc */
  114.     TranslateWinItem,            /* translateProc */
  115.     (Tk_ItemIndexProc *) NULL,        /* indexProc */
  116.     (Tk_ItemCursorProc *) NULL,        /* cursorProc */
  117.     (Tk_ItemSelectionProc *) NULL,    /* selectionProc */
  118.     (Tk_ItemInsertProc *) NULL,        /* insertProc */
  119.     (Tk_ItemDCharsProc *) NULL,        /* dTextProc */
  120.     (Tk_ItemType *) NULL        /* nextPtr */
  121. };
  122.  
  123.  
  124. /*
  125.  * The structure below defines the official type record for the
  126.  * placer:
  127.  */
  128.  
  129. static Tk_GeomMgr canvasGeomType = {
  130.     "canvas",                /* name */
  131.     WinItemRequestProc,            /* requestProc */
  132.     WinItemLostSlaveProc,        /* lostSlaveProc */
  133. };
  134.  
  135. /*
  136.  *--------------------------------------------------------------
  137.  *
  138.  * CreateWinItem --
  139.  *
  140.  *    This procedure is invoked to create a new window
  141.  *    item in a canvas.
  142.  *
  143.  * Results:
  144.  *    A standard Tcl return value.  If an error occurred in
  145.  *    creating the item, then an error message is left in
  146.  *    interp->result;  in this case itemPtr is
  147.  *    left uninitialized, so it can be safely freed by the
  148.  *    caller.
  149.  *
  150.  * Side effects:
  151.  *    A new window item is created.
  152.  *
  153.  *--------------------------------------------------------------
  154.  */
  155.  
  156. static int
  157. CreateWinItem(interp, canvas, itemPtr, argc, argv)
  158.     Tcl_Interp *interp;            /* Interpreter for error reporting. */
  159.     Tk_Canvas canvas;            /* Canvas to hold new item. */
  160.     Tk_Item *itemPtr;            /* Record to hold new item;  header
  161.                      * has been initialized by caller. */
  162.     int argc;                /* Number of arguments in argv. */
  163.     char **argv;            /* Arguments describing rectangle. */
  164. {
  165.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  166.  
  167.     if (argc < 2) {
  168.     Tcl_AppendResult(interp, "wrong # args:  should be \"",
  169.         Tk_PathName(Tk_CanvasTkwin(canvas)), "\" create ",
  170.         itemPtr->typePtr->name, " x y ?options?",
  171.         (char *) NULL);
  172.     return TCL_ERROR;
  173.     }
  174.  
  175.     /*
  176.      * Initialize item's record.
  177.      */
  178.  
  179.     winItemPtr->tkwin = NULL;
  180.     winItemPtr->width = 0;
  181.     winItemPtr->height = 0;
  182.     winItemPtr->anchor = TK_ANCHOR_CENTER;
  183.     winItemPtr->canvas = canvas;
  184.  
  185.     /*
  186.      * Process the arguments to fill in the item record.
  187.      */
  188.  
  189.     if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &winItemPtr->x) != TCL_OK)
  190.         || (Tk_CanvasGetCoord(interp, canvas, argv[1],
  191.         &winItemPtr->y) != TCL_OK)) {
  192.     return TCL_ERROR;
  193.     }
  194.  
  195.     if (ConfigureWinItem(interp, canvas, itemPtr, argc-2, argv+2, 0)
  196.         != TCL_OK) {
  197.     DeleteWinItem(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
  198.     return TCL_ERROR;
  199.     }
  200.     return TCL_OK;
  201. }
  202.  
  203. /*
  204.  *--------------------------------------------------------------
  205.  *
  206.  * WinItemCoords --
  207.  *
  208.  *    This procedure is invoked to process the "coords" widget
  209.  *    command on window items.  See the user documentation for
  210.  *    details on what it does.
  211.  *
  212.  * Results:
  213.  *    Returns TCL_OK or TCL_ERROR, and sets interp->result.
  214.  *
  215.  * Side effects:
  216.  *    The coordinates for the given item may be changed.
  217.  *
  218.  *--------------------------------------------------------------
  219.  */
  220.  
  221. static int
  222. WinItemCoords(interp, canvas, itemPtr, argc, argv)
  223.     Tcl_Interp *interp;            /* Used for error reporting. */
  224.     Tk_Canvas canvas;            /* Canvas containing item. */
  225.     Tk_Item *itemPtr;            /* Item whose coordinates are to be
  226.                      * read or modified. */
  227.     int argc;                /* Number of coordinates supplied in
  228.                      * argv. */
  229.     char **argv;            /* Array of coordinates: x1, y1,
  230.                      * x2, y2, ... */
  231. {
  232.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  233.     char x[TCL_DOUBLE_SPACE], y[TCL_DOUBLE_SPACE];
  234.  
  235.     if (argc == 0) {
  236.     Tcl_PrintDouble(interp, winItemPtr->x, x);
  237.     Tcl_PrintDouble(interp, winItemPtr->y, y);
  238.     Tcl_AppendResult(interp, x, " ", y, (char *) NULL);
  239.     } else if (argc == 2) {
  240.     if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &winItemPtr->x)
  241.         != TCL_OK) || (Tk_CanvasGetCoord(interp, canvas, argv[1],
  242.         &winItemPtr->y) != TCL_OK)) {
  243.         return TCL_ERROR;
  244.     }
  245.     ComputeWindowBbox(canvas, winItemPtr);
  246.     } else {
  247.     sprintf(interp->result,
  248.         "wrong # coordinates:  expected 0 or 2, got %d", argc);
  249.     return TCL_ERROR;
  250.     }
  251.     return TCL_OK;
  252. }
  253.  
  254. /*
  255.  *--------------------------------------------------------------
  256.  *
  257.  * ConfigureWinItem --
  258.  *
  259.  *    This procedure is invoked to configure various aspects
  260.  *    of a window item, such as its anchor position.
  261.  *
  262.  * Results:
  263.  *    A standard Tcl result code.  If an error occurs, then
  264.  *    an error message is left in interp->result.
  265.  *
  266.  * Side effects:
  267.  *    Configuration information may be set for itemPtr.
  268.  *
  269.  *--------------------------------------------------------------
  270.  */
  271.  
  272. static int
  273. ConfigureWinItem(interp, canvas, itemPtr, argc, argv, flags)
  274.     Tcl_Interp *interp;        /* Used for error reporting. */
  275.     Tk_Canvas canvas;        /* Canvas containing itemPtr. */
  276.     Tk_Item *itemPtr;        /* Window item to reconfigure. */
  277.     int argc;            /* Number of elements in argv.  */
  278.     char **argv;        /* Arguments describing things to configure. */
  279.     int flags;            /* Flags to pass to Tk_ConfigureWidget. */
  280. {
  281.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  282.     Tk_Window oldWindow;
  283.     Tk_Window canvasTkwin;
  284.  
  285.     oldWindow = winItemPtr->tkwin;
  286.     canvasTkwin = Tk_CanvasTkwin(canvas);
  287.     if (Tk_ConfigureWidget(interp, canvasTkwin, configSpecs, argc, argv,
  288.         (char *) winItemPtr, flags) != TCL_OK) {
  289.     return TCL_ERROR;
  290.     }
  291.  
  292.     /*
  293.      * A few of the options require additional processing.
  294.      */
  295.  
  296.     if (oldWindow != winItemPtr->tkwin) {
  297.     if (oldWindow != NULL) {
  298.         Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
  299.             WinItemStructureProc, (ClientData) winItemPtr);
  300.         Tk_ManageGeometry(oldWindow, (Tk_GeomMgr *) NULL,
  301.             (ClientData) NULL);
  302.         Tk_UnmaintainGeometry(oldWindow, canvasTkwin);
  303.         Tk_UnmapWindow(oldWindow);
  304.     }
  305.     if (winItemPtr->tkwin != NULL) {
  306.         Tk_Window ancestor, parent;
  307.  
  308.         /*
  309.          * Make sure that the canvas is either the parent of the
  310.          * window associated with the item or a descendant of that
  311.          * parent.  Also, don't allow a top-level window to be
  312.          * managed inside a canvas.
  313.          */
  314.  
  315.         parent = Tk_Parent(winItemPtr->tkwin);
  316.         for (ancestor = canvasTkwin; ;
  317.             ancestor = Tk_Parent(ancestor)) {
  318.         if (ancestor == parent) {
  319.             break;
  320.         }
  321.         if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) {
  322.             badWindow:
  323.             Tcl_AppendResult(interp, "can't use ",
  324.                 Tk_PathName(winItemPtr->tkwin),
  325.                 " in a window item of this canvas", (char *) NULL);
  326.             winItemPtr->tkwin = NULL;
  327.             return TCL_ERROR;
  328.         }
  329.         }
  330.         if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_LEVEL) {
  331.         goto badWindow;
  332.         }
  333.         if (winItemPtr->tkwin == canvasTkwin) {
  334.         goto badWindow;
  335.         }
  336.         Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  337.             WinItemStructureProc, (ClientData) winItemPtr);
  338.         Tk_ManageGeometry(winItemPtr->tkwin, &canvasGeomType,
  339.             (ClientData) winItemPtr);
  340.     }
  341.     }
  342.  
  343.     ComputeWindowBbox(canvas, winItemPtr);
  344.  
  345.     return TCL_OK;
  346. }
  347.  
  348. /*
  349.  *--------------------------------------------------------------
  350.  *
  351.  * DeleteWinItem --
  352.  *
  353.  *    This procedure is called to clean up the data structure
  354.  *    associated with a window item.
  355.  *
  356.  * Results:
  357.  *    None.
  358.  *
  359.  * Side effects:
  360.  *    Resources associated with itemPtr are released.
  361.  *
  362.  *--------------------------------------------------------------
  363.  */
  364.  
  365. static void
  366. DeleteWinItem(canvas, itemPtr, display)
  367.     Tk_Canvas canvas;            /* Overall info about widget. */
  368.     Tk_Item *itemPtr;            /* Item that is being deleted. */
  369.     Display *display;            /* Display containing window for
  370.                      * canvas. */
  371. {
  372.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  373.     Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
  374.  
  375.     if (winItemPtr->tkwin != NULL) {
  376.     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  377.         WinItemStructureProc, (ClientData) winItemPtr);
  378.     Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeomMgr *) NULL,
  379.         (ClientData) NULL);
  380.     if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
  381.         Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
  382.     }
  383.     Tk_UnmapWindow(winItemPtr->tkwin);
  384.     }
  385. }
  386.  
  387. /*
  388.  *--------------------------------------------------------------
  389.  *
  390.  * ComputeWindowBbox --
  391.  *
  392.  *    This procedure is invoked to compute the bounding box of
  393.  *    all the pixels that may be drawn as part of a window item.
  394.  *    This procedure is where the child window's placement is
  395.  *    computed.
  396.  *
  397.  * Results:
  398.  *    None.
  399.  *
  400.  * Side effects:
  401.  *    The fields x1, y1, x2, and y2 are updated in the header
  402.  *    for itemPtr.
  403.  *
  404.  *--------------------------------------------------------------
  405.  */
  406.  
  407. static void
  408. ComputeWindowBbox(canvas, winItemPtr)
  409.     Tk_Canvas canvas;            /* Canvas that contains item. */
  410.     WindowItem *winItemPtr;        /* Item whose bbox is to be
  411.                      * recomputed. */
  412. {
  413.     int width, height, x, y;
  414.  
  415.     x = winItemPtr->x + 0.5;
  416.     y = winItemPtr->y + 0.5;
  417.  
  418.     if (winItemPtr->tkwin == NULL) {
  419.     winItemPtr->header.x1 = winItemPtr->header.x2 = x;
  420.     winItemPtr->header.y1 = winItemPtr->header.y2 = y;
  421.     return;
  422.     }
  423.  
  424.     /*
  425.      * Compute dimensions of window.
  426.      */
  427.  
  428.     width = winItemPtr->width;
  429.     if (width <= 0) {
  430.     width = Tk_ReqWidth(winItemPtr->tkwin);
  431.     if (width <= 0) {
  432.         width = 1;
  433.     }
  434.     }
  435.     height = winItemPtr->height;
  436.     if (height <= 0) {
  437.     height = Tk_ReqHeight(winItemPtr->tkwin);
  438.     if (height <= 0) {
  439.         height = 1;
  440.     }
  441.     }
  442.  
  443.     /*
  444.      * Compute location of window, using anchor information.
  445.      */
  446.  
  447.     switch (winItemPtr->anchor) {
  448.     case TK_ANCHOR_N:
  449.         x -= width/2;
  450.         break;
  451.     case TK_ANCHOR_NE:
  452.         x -= width;
  453.         break;
  454.     case TK_ANCHOR_E:
  455.         x -= width;
  456.         y -= height/2;
  457.         break;
  458.     case TK_ANCHOR_SE:
  459.         x -= width;
  460.         y -= height;
  461.         break;
  462.     case TK_ANCHOR_S:
  463.         x -= width/2;
  464.         y -= height;
  465.         break;
  466.     case TK_ANCHOR_SW:
  467.         y -= height;
  468.         break;
  469.     case TK_ANCHOR_W:
  470.         y -= height/2;
  471.         break;
  472.     case TK_ANCHOR_NW:
  473.         break;
  474.     case TK_ANCHOR_CENTER:
  475.         x -= width/2;
  476.         y -= height/2;
  477.         break;
  478.     }
  479.  
  480.     /*
  481.      * Store the information in the item header.
  482.      */
  483.  
  484.     winItemPtr->header.x1 = x;
  485.     winItemPtr->header.y1 = y;
  486.     winItemPtr->header.x2 = x + width;
  487.     winItemPtr->header.y2 = y + height;
  488. }
  489.  
  490. /*
  491.  *--------------------------------------------------------------
  492.  *
  493.  * DisplayWinItem --
  494.  *
  495.  *    This procedure is invoked to "draw" a window item in a given
  496.  *    drawable.  Since the window draws itself, we needn't do any
  497.  *    actual redisplay here.  However, this procedure takes care
  498.  *    of actually repositioning the child window so that it occupies
  499.  *    the correct screen position.
  500.  *
  501.  * Results:
  502.  *    None.
  503.  *
  504.  * Side effects:
  505.  *    The child window's position may get changed.  Note: this
  506.  *    procedure gets called both when a window needs to be displayed
  507.  *    and when it ceases to be visible on the screen (e.g. it was
  508.  *    scrolled or moved off-screen or the enclosing canvas is
  509.  *    unmapped).
  510.  *
  511.  *--------------------------------------------------------------
  512.  */
  513.  
  514. static void
  515. DisplayWinItem(canvas, itemPtr, display, drawable, regionX, regionY,
  516.     regionWidth, regionHeight)
  517.     Tk_Canvas canvas;            /* Canvas that contains item. */
  518.     Tk_Item *itemPtr;            /* Item to be displayed. */
  519.     Display *display;            /* Display on which to draw item. */
  520.     Drawable drawable;            /* Pixmap or window in which to draw
  521.                      * item. */
  522.     int regionX, regionY, regionWidth, regionHeight;
  523.                     /* Describes region of canvas that
  524.                      * must be redisplayed (not used). */
  525. {
  526.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  527.     int width, height;
  528.     short x, y;
  529.     Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
  530.  
  531.     if (winItemPtr->tkwin == NULL) {
  532.     return;
  533.     }
  534.  
  535.     Tk_CanvasWindowCoords(canvas, (double) winItemPtr->header.x1,
  536.         (double) winItemPtr->header.y1, &x, &y);
  537.     width = winItemPtr->header.x2 - winItemPtr->header.x1;
  538.     height = winItemPtr->header.y2 - winItemPtr->header.y1;
  539.  
  540.     /*
  541.      * Reposition and map the window (but in different ways depending
  542.      * on whether the canvas is the window's parent).
  543.      */
  544.  
  545.     if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
  546.     if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
  547.         || (width != Tk_Width(winItemPtr->tkwin))
  548.         || (height != Tk_Height(winItemPtr->tkwin))) {
  549.         Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
  550.     }
  551.     Tk_MapWindow(winItemPtr->tkwin);
  552.     } else {
  553.     Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
  554.         width, height);
  555.     }
  556. }
  557.  
  558. /*
  559.  *--------------------------------------------------------------
  560.  *
  561.  * WinItemToPoint --
  562.  *
  563.  *    Computes the distance from a given point to a given
  564.  *    rectangle, in canvas units.
  565.  *
  566.  * Results:
  567.  *    The return value is 0 if the point whose x and y coordinates
  568.  *    are coordPtr[0] and coordPtr[1] is inside the window.  If the
  569.  *    point isn't inside the window then the return value is the
  570.  *    distance from the point to the window.
  571.  *
  572.  * Side effects:
  573.  *    None.
  574.  *
  575.  *--------------------------------------------------------------
  576.  */
  577.  
  578. static double
  579. WinItemToPoint(canvas, itemPtr, pointPtr)
  580.     Tk_Canvas canvas;        /* Canvas containing item. */
  581.     Tk_Item *itemPtr;        /* Item to check against point. */
  582.     double *pointPtr;        /* Pointer to x and y coordinates. */
  583. {
  584.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  585.     double x1, x2, y1, y2, xDiff, yDiff;
  586.  
  587.     x1 = winItemPtr->header.x1;
  588.     y1 = winItemPtr->header.y1;
  589.     x2 = winItemPtr->header.x2;
  590.     y2 = winItemPtr->header.y2;
  591.  
  592.     /*
  593.      * Point is outside rectangle.
  594.      */
  595.  
  596.     if (pointPtr[0] < x1) {
  597.     xDiff = x1 - pointPtr[0];
  598.     } else if (pointPtr[0] >= x2)  {
  599.     xDiff = pointPtr[0] + 1 - x2;
  600.     } else {
  601.     xDiff = 0;
  602.     }
  603.  
  604.     if (pointPtr[1] < y1) {
  605.     yDiff = y1 - pointPtr[1];
  606.     } else if (pointPtr[1] >= y2)  {
  607.     yDiff = pointPtr[1] + 1 - y2;
  608.     } else {
  609.     yDiff = 0;
  610.     }
  611.  
  612.     return hypot(xDiff, yDiff);
  613. }
  614.  
  615. /*
  616.  *--------------------------------------------------------------
  617.  *
  618.  * WinItemToArea --
  619.  *
  620.  *    This procedure is called to determine whether an item
  621.  *    lies entirely inside, entirely outside, or overlapping
  622.  *    a given rectangle.
  623.  *
  624.  * Results:
  625.  *    -1 is returned if the item is entirely outside the area
  626.  *    given by rectPtr, 0 if it overlaps, and 1 if it is entirely
  627.  *    inside the given area.
  628.  *
  629.  * Side effects:
  630.  *    None.
  631.  *
  632.  *--------------------------------------------------------------
  633.  */
  634.  
  635. static int
  636. WinItemToArea(canvas, itemPtr, rectPtr)
  637.     Tk_Canvas canvas;        /* Canvas containing item. */
  638.     Tk_Item *itemPtr;        /* Item to check against rectangle. */
  639.     double *rectPtr;        /* Pointer to array of four coordinates
  640.                  * (x1, y1, x2, y2) describing rectangular
  641.                  * area.  */
  642. {
  643.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  644.  
  645.     if ((rectPtr[2] <= winItemPtr->header.x1)
  646.         || (rectPtr[0] >= winItemPtr->header.x2)
  647.         || (rectPtr[3] <= winItemPtr->header.y1)
  648.         || (rectPtr[1] >= winItemPtr->header.y2)) {
  649.     return -1;
  650.     }
  651.     if ((rectPtr[0] <= winItemPtr->header.x1)
  652.         && (rectPtr[1] <= winItemPtr->header.y1)
  653.         && (rectPtr[2] >= winItemPtr->header.x2)
  654.         && (rectPtr[3] >= winItemPtr->header.y2)) {
  655.     return 1;
  656.     }
  657.     return 0;
  658. }
  659.  
  660. /*
  661.  *--------------------------------------------------------------
  662.  *
  663.  * ScaleWinItem --
  664.  *
  665.  *    This procedure is invoked to rescale a rectangle or oval
  666.  *    item.
  667.  *
  668.  * Results:
  669.  *    None.
  670.  *
  671.  * Side effects:
  672.  *    The rectangle or oval referred to by itemPtr is rescaled
  673.  *    so that the following transformation is applied to all
  674.  *    point coordinates:
  675.  *        x' = originX + scaleX*(x-originX)
  676.  *        y' = originY + scaleY*(y-originY)
  677.  *
  678.  *--------------------------------------------------------------
  679.  */
  680.  
  681. static void
  682. ScaleWinItem(canvas, itemPtr, originX, originY, scaleX, scaleY)
  683.     Tk_Canvas canvas;            /* Canvas containing rectangle. */
  684.     Tk_Item *itemPtr;            /* Rectangle to be scaled. */
  685.     double originX, originY;        /* Origin about which to scale rect. */
  686.     double scaleX;            /* Amount to scale in X direction. */
  687.     double scaleY;            /* Amount to scale in Y direction. */
  688. {
  689.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  690.  
  691.     winItemPtr->x = originX + scaleX*(winItemPtr->x - originX);
  692.     winItemPtr->y = originY + scaleY*(winItemPtr->y - originY);
  693.     if (winItemPtr->width > 0) {
  694.     winItemPtr->width = scaleY*winItemPtr->width;
  695.     }
  696.     if (winItemPtr->height > 0) {
  697.     winItemPtr->height = scaleY*winItemPtr->height;
  698.     }
  699.     ComputeWindowBbox(canvas, winItemPtr);
  700. }
  701.  
  702. /*
  703.  *--------------------------------------------------------------
  704.  *
  705.  * TranslateWinItem --
  706.  *
  707.  *    This procedure is called to move a rectangle or oval by a
  708.  *    given amount.
  709.  *
  710.  * Results:
  711.  *    None.
  712.  *
  713.  * Side effects:
  714.  *    The position of the rectangle or oval is offset by
  715.  *    (xDelta, yDelta), and the bounding box is updated in the
  716.  *    generic part of the item structure.
  717.  *
  718.  *--------------------------------------------------------------
  719.  */
  720.  
  721. static void
  722. TranslateWinItem(canvas, itemPtr, deltaX, deltaY)
  723.     Tk_Canvas canvas;            /* Canvas containing item. */
  724.     Tk_Item *itemPtr;            /* Item that is being moved. */
  725.     double deltaX, deltaY;        /* Amount by which item is to be
  726.                      * moved. */
  727. {
  728.     WindowItem *winItemPtr = (WindowItem *) itemPtr;
  729.  
  730.     winItemPtr->x += deltaX;
  731.     winItemPtr->y += deltaY;
  732.     ComputeWindowBbox(canvas, winItemPtr);
  733. }
  734.  
  735. /*
  736.  *--------------------------------------------------------------
  737.  *
  738.  * WinItemStructureProc --
  739.  *
  740.  *    This procedure is invoked whenever StructureNotify events
  741.  *    occur for a window that's managed as part of a canvas window
  742.  *    item.  This procudure's only purpose is to clean up when
  743.  *    windows are deleted.
  744.  *
  745.  * Results:
  746.  *    None.
  747.  *
  748.  * Side effects:
  749.  *    The window is disassociated from the window item when it is
  750.  *    deleted.
  751.  *
  752.  *--------------------------------------------------------------
  753.  */
  754.  
  755. static void
  756. WinItemStructureProc(clientData, eventPtr)
  757.     ClientData clientData;    /* Pointer to record describing window item. */
  758.     XEvent *eventPtr;        /* Describes what just happened. */
  759. {
  760.     WindowItem *winItemPtr = (WindowItem *) clientData;
  761.  
  762.     if (eventPtr->type == DestroyNotify) {
  763.     winItemPtr->tkwin = NULL;
  764.     }
  765. }
  766.  
  767. /*
  768.  *--------------------------------------------------------------
  769.  *
  770.  * WinItemRequestProc --
  771.  *
  772.  *    This procedure is invoked whenever a window that's associated
  773.  *    with a window canvas item changes its requested dimensions.
  774.  *
  775.  * Results:
  776.  *    None.
  777.  *
  778.  * Side effects:
  779.  *    The size and location on the screen of the window may change,
  780.  *    depending on the options specified for the window item.
  781.  *
  782.  *--------------------------------------------------------------
  783.  */
  784.  
  785. static void
  786. WinItemRequestProc(clientData, tkwin)
  787.     ClientData clientData;        /* Pointer to record for window item. */
  788.     Tk_Window tkwin;            /* Window that changed its desired
  789.                      * size. */
  790. {
  791.     WindowItem *winItemPtr = (WindowItem *) clientData;
  792.  
  793.     ComputeWindowBbox(winItemPtr->canvas, winItemPtr);
  794.     DisplayWinItem(winItemPtr->canvas, (Tk_Item *) winItemPtr,
  795.         (Display *) NULL, (Drawable) None, 0, 0, 0, 0);
  796. }
  797.  
  798. /*
  799.  *--------------------------------------------------------------
  800.  *
  801.  * WinItemLostSlaveProc --
  802.  *
  803.  *    This procedure is invoked by Tk whenever some other geometry
  804.  *    claims control over a slave that used to be managed by us.
  805.  *
  806.  * Results:
  807.  *    None.
  808.  *
  809.  * Side effects:
  810.  *    Forgets all canvas-related information about the slave.
  811.  *
  812.  *--------------------------------------------------------------
  813.  */
  814.  
  815.     /* ARGSUSED */
  816. static void
  817. WinItemLostSlaveProc(clientData, tkwin)
  818.     ClientData clientData;    /* WindowItem structure for slave window that
  819.                  * was stolen away. */
  820.     Tk_Window tkwin;        /* Tk's handle for the slave window. */
  821. {
  822.     WindowItem *winItemPtr = (WindowItem *) clientData;
  823.     Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
  824.  
  825.     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  826.         WinItemStructureProc, (ClientData) winItemPtr);
  827.     if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
  828.     Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
  829.     }
  830.     Tk_UnmapWindow(winItemPtr->tkwin);
  831.     winItemPtr->tkwin = NULL;
  832. }
  833.